package org.smart4j.framework.common.helper;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

/**
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-02-08 12:45
 */
@Data
@Slf4j
public final class ServletHelper {
    private final static ThreadLocal<ServletHelper> SERVLET_HOLDER = new ThreadLocal<>();
    private HttpServletRequest request;
    private HttpServletResponse response;

    public ServletHelper(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public static void init(HttpServletRequest request, HttpServletResponse response) {
        SERVLET_HOLDER.set(new ServletHelper(request, response));
    }

    public static void destroy() {
        SERVLET_HOLDER.remove();
    }

    public static HttpServletRequest getRequest() {
        ServletHelper servletHelper = SERVLET_HOLDER.get();
        if (Objects.isNull(servletHelper)) {
            return null;
        }
        return servletHelper.request;
    }

    public static HttpServletResponse getResponse() {
        ServletHelper servletHelper = SERVLET_HOLDER.get();
        if (Objects.isNull(servletHelper)) {
            return null;
        }
        return servletHelper.response;
    }

    public static HttpSession getSession() {
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)) {
            return null;
        }
        return request.getSession();
    }

    public static ServletContext getServletContext() {
        HttpServletRequest request = getRequest();
        if (Objects.isNull(request)) {
            return null;
        }
        return request.getServletContext();
    }

    public static void setRequestAttribute(String key, Object value) {
        HttpServletRequest request = getRequest();
        request.setAttribute(key, value);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getRequestAttribute(String key) {
        HttpServletRequest request = getRequest();
        return (T) request.getAttribute(key);
    }

    public static void removeRequestAttribute(String key) {
        HttpServletRequest request = getRequest();
        request.removeAttribute(key);
    }

    public static void setSessionAttribute(String key, Object value) {
        HttpSession session = getSession();
        session.setAttribute(key, value);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getSessionAttribute(String key) {
        HttpSession session = getSession();
        return (T) session.getAttribute(key);
    }

    public static void removeSessionAttribute(String key) {
        HttpSession session = getSession();
        session.removeAttribute(key);
    }

    public static void invalidateSession() {
        HttpSession session = getSession();
        session.invalidate();
    }

    public static void sendRedirect(String location) {
        try {
            getResponse().sendRedirect(getServletContext().getContextPath().concat(location));
        } catch (IOException e) {
            log.error("redirect failed!", e);
        }
    }

    public static void forward(String location) {
        try {
            getRequest().getRequestDispatcher(getServletContext().getContextPath().concat(location)).forward(getRequest(), getResponse());
        } catch (Exception e) {
            log.error("forward failed!", e);
        }
    }
}
